home *** CD-ROM | disk | FTP | other *** search
/ BCI NET 2 / BCI NET 2.iso / archives / programming / source / xdme_1.84_src.lha / XDME / Util / Var / node.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-12-22  |  18.4 KB  |  872 lines

  1.  
  2. #include <exec/types.h>
  3. #include <lists.h>
  4.  
  5.  
  6. #include "node.h"
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <assert.h>
  11. #include <clib/alib_protos.h>
  12. #include <clib/exec_protos.h>
  13.  
  14. #define Prototype extern
  15. #define STREAM void*
  16. #define DSTR struct _DSTR *
  17. #include "protos.h"
  18.  
  19. #include "Dyn.h"
  20.  
  21. #define strupper strupr
  22. #define strlower strlwr
  23.  
  24.  
  25. #define NEW(x) x = calloc(sizeof(*x), 1)
  26. #define RemHead     (void *)RemHead
  27. #define FindName    _FindName
  28. #ifdef _DCC
  29. #define bzero(p,s) setmem(p,s,0)
  30. #endif
  31.  
  32.  
  33. static char _buffer[256];
  34. static struct List NStack, _private_init;
  35.  
  36.  
  37.  
  38. struct PNode {
  39.     struct Node Node;
  40.     struct PNode*Parent;
  41.     DSTR     Text;
  42. #ifndef OLD
  43.     struct PNode*Type;
  44. #endif
  45.     struct List  Subs;
  46.     struct List  Defs;
  47.     struct List  Types;
  48.     struct List  Attrs;
  49. }; /* struct PNode */
  50.  
  51. #ifdef OLD
  52. #define Type Node.ln_Type
  53. #define NODE_GetType(n) DLL_NumToNode(&(n)->Parent->Types, (n)->Type)
  54. #define T_TYPE long
  55. #else
  56. #define NODE_GetType(n) n->Type
  57. #define T_TYPE APTR
  58. #endif
  59.  
  60.  
  61. int   presetflags = 0;
  62. T_TYPE presettype = 0L;
  63. int   level      = 0;
  64. APTR NODE_root = NULL;
  65.  
  66.  
  67. static int NODE_compare (struct Node *n, struct Node *m, APTR dummy) {
  68.     return stricmp(n->ln_Name, m->ln_Name);
  69. } /* NODE_compare */
  70.  
  71. void AddSorted (struct List *l, struct PNode *p) {
  72.     DLL_AddSorted (l, (struct Node *)p, NODE_compare, NULL);
  73. } /* AddSorted */
  74.  
  75. static int NODE_check (struct Node *n, char *name) {
  76.     return stricmp(n->ln_Name, name) ? 0: 1;
  77. } /* NODE_check */
  78.  
  79. struct PNode * FindName (struct List *l, char *name) {
  80.     return (struct PNode *)DLL_Search(l, NODE_check, name);
  81. } /* FindName */
  82.  
  83.  
  84.  
  85. /*  das hier wird noch wesentlich komplexer ... */
  86. /*  wir fragen noch die parents ab, ob dort */
  87. /*  evtl ein type deiniert ist    */
  88. /*  wir sollten noch abfragen, ob es ein default */
  89. /*  gibt, das types definiert, ... */
  90.  
  91. unsigned long NODE_IsType (const char *name) {
  92.     struct PNode *n, *m;
  93.     n = GetHead(&NStack);
  94. //printf ("IsType '%s' (in %s/) ", name, ((ULONG)n > 10)? n->Node.ln_Name: "-", (((ULONG)n > 10) && n->Type)? n->Type->Node.ln_Name: "-");
  95.     if (!n) {
  96. //puts ("n-NO");
  97.     return NULL;
  98.     }
  99.     strcpy  (_buffer, name);
  100.     strupper(_buffer);
  101.     if (m = FindName(&n->Types, _buffer)) {
  102. //puts ("d-YES");
  103.     return (unsigned long)m;
  104.     }
  105. #ifndef OLD
  106.     if (n->Type && (m = NODE_GetType(n))) {
  107. //printf ("n=%08lx/%s; nt=%08lx/%s ", n, n->Node.ln_Name, m, m->Node.ln_Name);
  108.     if (m = FindName(&m->Types, _buffer)) {
  109. //puts ("t-YES");
  110.         return (unsigned long)m;
  111.     }
  112.     } else {
  113.     // Das SOLLTE heissen: if m = GetDefault_of_n && m = findname m_types_buffer
  114.     if ((m = n->Parent) && (m->Type) && (m = NODE_GetType(m))) {
  115.         if ((m = FindName(&m->Subs, n->Node.ln_Name))) {
  116.         if ((m = FindName(&m->Types, _buffer))) {
  117. //puts ("i-YES");
  118.             return (ULONG)m;
  119.         }
  120.         }
  121.     }
  122.     } /* if */
  123. #endif
  124. //puts ("l-NO");
  125.     return 0;
  126. } /* NODE_IsType */
  127.  
  128. static unsigned long NODE_IsNeeded (const char *name) {
  129.     struct PNode *n;
  130.     n = GetHead(&NStack);
  131.     if (!n)
  132.     return 0;
  133.  
  134.     if (n->Parent && ((unsigned long)name > 10)) {
  135.     struct PNode *m = n->Parent;
  136.     // all `Types' Uppercase
  137.     if (1 == (long)m->Node.ln_Name)
  138.         return 1;
  139.     else
  140.     // all `Needed' Uppercase
  141.     if (2 == (long)m->Node.ln_Name)
  142.         return 1;
  143.     else {
  144.     // all `needed' entries of subs Uppercase
  145.         strcpy (_buffer, name);
  146.         strupper(_buffer);
  147.         if ((m->Parent) && (FindName(&m->Parent->Attrs, _buffer))) {
  148.         return 1;
  149.         } else
  150.         if ((m->Parent) && (m = NODE_GetType(m)) && (FindName(&m->Subs, _buffer)))
  151.         {
  152.         return 1;
  153.         } /* if */
  154.     } /* if */
  155.     } /* if */
  156.     return 0;
  157. } /* NODE_IsNeeded */
  158.  
  159.  
  160.  
  161. void NODE_push (struct PNode *n) {
  162. ++level;
  163.     Remove (&n->Node);
  164.     AddHead(&NStack, &n->Node);
  165. } /* NODE_push */
  166.  
  167.  
  168. void NODE_PUSH (char *name, int full) {
  169.     struct PNode *n;
  170.  
  171. //printf ("PUSH %s\n", name);
  172.     /* eigentlich muessten wir hier duplikate eliminieren oder vereinigen */
  173.  
  174.     n = GetHead(&NStack);
  175.     if (name && n)
  176.     n = (struct PNode *)FindName(&n->Subs, name);
  177.     else n =NULL;
  178.     if (!n) {
  179.     if (!full)
  180.         return;
  181.  
  182.     NEW(n);
  183.     assert(n != NULL);
  184.     bzero(n, sizeof(*n));
  185.  
  186.     NewList(&n->Subs);
  187.     NewList(&n->Defs);
  188.     NewList(&n->Types);
  189.     NewList(&n->Attrs);
  190.  
  191.     n->Node.ln_Name = name;
  192.     n->Node.ln_Pri    = presetflags;
  193.     n->Parent    = GetHead(&NStack);
  194.     n->Type     = presettype;
  195.  
  196.     // to-upper decision
  197.     if (NODE_IsNeeded(name))
  198.         strupper(name);
  199.  
  200.     AddHead(&_private_init, &n->Node);
  201.     } else {
  202.  
  203. extern int lineno; struct PNode *p = n->Parent;
  204. printf ("\t/* \"%s\", %d/l%d/p=%s/t=%d */\n", name, level + 1, lineno, p->Node.ln_Name? p->Node.ln_Name: "<DEF>", presettype);
  205. printf ("\t/* **************** EXISTS ! */\n");
  206. printf ("OldVal=%s\n", DynValue(&n->Text));
  207.  
  208.     assert (!presettype || (presettype == n->Type));
  209.     if (full)
  210.         free (name);
  211.     } /* if */
  212.  
  213.     NODE_push(n);
  214.  
  215.     presetflags = 0; presettype = 0L;
  216. } /* NODE_PUSH */
  217.  
  218.  
  219. void NODE_drop (struct PNode *n, BOOL full) {
  220.  
  221. /* printf ("dropping %s\n", n->Node.ln_Name); */
  222.     {
  223.     struct PNode *m;
  224.     while (m = RemHead(&n->Subs)) {
  225.         NODE_drop(m, 1);
  226.     } /* while */
  227.     while (m = RemHead(&n->Defs)) {
  228.         NODE_drop(m, 1);
  229.     } /* while */
  230.     while (m = RemHead(&n->Types)) {
  231.         NODE_drop(m, 1);
  232.     } /* while */
  233.     while (m = RemHead(&n->Attrs)) {
  234.         NODE_drop(m, 1);
  235.     } /* while */
  236.     }
  237.     DynClear(&n->Text);
  238.     /* free(n->Reference); */
  239.     if (full) {
  240.     free(n->Node.ln_Name);
  241.     free(n);
  242.     } /* if */
  243. } /* NODE_drop */
  244.  
  245.  
  246. void NODE_POP (void) {
  247.     struct PNode *n, *m;
  248.  
  249. level --;
  250.  
  251.     n = RemHead(&NStack);
  252. //printf ("POP %s\n", n->Node.ln_Name);
  253.     assert(n != NULL);
  254.     if ((m = n->Parent)) {
  255.     if (n->Node.ln_Name < (BYTE*)10) {
  256.         if (n->Node.ln_Name == NULL)
  257.         AddTail (&m->Defs, &n->Node);
  258.         else {
  259.         struct PNode *x, *y;
  260.         if (n->Node.ln_Name == (char *)1L) {
  261.             for (x = GetHead (&n->Subs); x; x = y) {
  262.             y = GetSucc(x);
  263.             Remove    (&x->Node);
  264.             AddTail (&m->Types, &x->Node);
  265.             x->Parent = m;
  266.             } /* for */
  267.             //DLL_Join(&m->Types, &n->Subs);
  268.         } if (n->Node.ln_Name == (char *)2L) {
  269.             for (x = GetHead (&n->Subs); x; x = y) {
  270.             y = GetSucc(x);
  271.             Remove    (&x->Node);
  272.             AddTail (&m->Attrs, &x->Node);
  273.             x->Parent = m;
  274.             } /* for */
  275.             //DLL_Join(&m->Attrs, &n->Subs);
  276.         }
  277.         NODE_drop(n, 1);
  278.         } /* if */
  279.     } else
  280.         AddSorted(&m->Subs, n);
  281.     } else
  282.     assert (("POP on rootlevel!", 0));
  283.  
  284. } /* NODE_POP */
  285.  
  286.  
  287. void NODE_CLEAR (void) {
  288.     struct PNode *n;
  289.     n = GetHead(&NStack);
  290.     assert(n != NULL);
  291.     NODE_drop(n, 0);
  292. } /* NODE_CLEAR */
  293.  
  294. void NODE_TEXT (char *text) {
  295.     struct PNode *n;
  296.     n = GetHead(&NStack);
  297.     assert(n != NULL);
  298.  
  299.     DynCat(&n->Text, text);
  300.     free(text);
  301. } /* NODE_TEXT */
  302.  
  303.  
  304.  
  305.  
  306. void NODE_access (int type) {
  307.     presetflags = presetflags & ~(3) | type;
  308. } /* NODE_access */
  309.  
  310. void NODE_type (const char *name) {
  311. #ifdef OLD
  312.     presettype = DLL_NodeToNum(NULL, (struct Node *)NODE_IsType(name));
  313. #else
  314.     presettype = (T_TYPE)NODE_IsType(name);
  315. #endif
  316. } /* NODE_type */
  317.  
  318. void NODE_spc (int type) {
  319.     presetflags = presetflags & ~(3 << 2) | type;
  320. } /* NODE_spc */
  321.  
  322.  
  323.  
  324.  
  325.  
  326. struct PNode * NODE_lock (struct PNode *n, const char *sub, int level)
  327. {
  328.     struct PNode *m;
  329. //printf ("Q:4'%s'in'%s'\n", sub, n->Node.ln_Name);
  330.  
  331.     // explicite goback ...
  332.     while (((*sub == '/') || (*sub == ':')) && n) {
  333.     if (*sub == '/') {
  334.         n = n->Parent;
  335.         ++sub;
  336.     } /* if */
  337.  
  338.     if (*sub == ':') {
  339.         n = NODE_root;
  340.         ++sub;
  341.     } /* if */
  342.  
  343.     if (!*sub) {
  344.         return n;
  345.     } /* if */
  346.     } /* if */
  347.  
  348.  
  349.     m = FindName (&n->Subs, (char *)sub);
  350.     if (m)
  351.     return m;
  352.  
  353.     m = n->Parent;
  354.     if (m) {
  355.     /* die defaults nur scannen, wenn wir nicht in den defaults sind ... */
  356.     if (10 < (unsigned long)n->Node.ln_Name) {
  357.         struct PNode *d;
  358.  
  359.         /* zuerst Defaults ... */
  360.         for (d = GetHead (&m->Defs); d; d = GetSucc(d)) {
  361.         if (d->Type == n->Type && d != n) {
  362.             d = NODE_lock(d, sub, 0);
  363.             if (d) return d;
  364.             break;
  365.         } /* if */
  366.         } /* for */
  367.  
  368.         /* dann Type ... */
  369.         if ((d = NODE_GetType(n)) && d != n)
  370.         {
  371.         d = NODE_lock(d, sub, 0);
  372.         if (d) return d;
  373.         } /* if */
  374.     } /* if */
  375.  
  376.     /* schliesslich auf Parentebene weitersuchen */
  377.     if (level)
  378.         return NODE_lock(m, sub, level - 1);
  379.  
  380.     } /* if */
  381.  
  382.     return NULL;
  383. } /* NODE_lock */
  384.  
  385. #define _NOLIMIT_  -1
  386. #define _ONELEVEL_  0
  387.  
  388.  
  389. char * _NODE_sub (struct PNode *n, const char *sub) {
  390.     struct PNode *m;
  391.  
  392.     m = NODE_lock (n, (char *)sub, _NOLIMIT_);
  393.     if (m)
  394.     return (char *)(DynLen(&m->Text)? DynValue(&m->Text) :
  395.             /* (char *)((m->Reference != NULL) ? m->Reference : */
  396.                         (char *)NULL);
  397.  
  398.     return NULL;
  399. } /* NODE_sub */
  400.  
  401. void Log(char *, int, struct PNode*);
  402. void ShowLog (void);
  403.  
  404.  
  405. #define S_ITERATE_ "@ITERATE@"
  406. #define L_ITERATE_ 9
  407. #define S_IF_       "@IF@"
  408. #define L_IF_       4
  409. #define S_WITH_    "@WITH@"
  410. #define L_WITH_    6
  411. #define S_FOREACH_ "@FOREACH@"
  412. #define L_FOREACH_ 9
  413. #define S_TOUPPER_ "@TOUPPER@"
  414. #define L_TOUPPER_ 9
  415. #define S_TOLOWER_ "@TOLOWER@"
  416. #define L_TOLOWER_ 9
  417. #define _END_       '@'
  418. #define _NAME_       "NAME"
  419. #define _VALUE_    "VALUE"
  420. #define _INDEX_    "IDX"
  421. #define _TINDEX_   "TIDX"
  422. #define _SETTABLE_ "SETTABLE"
  423. #define _GETTABLE_ "GETTABLE"
  424.  
  425. int _NumQueries = 0;
  426. int Index, TIndex;
  427.  
  428. char * NODE_sub (struct PNode *n, char *name);
  429.  
  430.  
  431. BOOL NODE_hunt (DSTR *dest, char *tmplt, struct PNode *n)
  432. {
  433.     static int REK = 0;
  434.     int nq_inter = _NumQueries, loops = 1;
  435.     DSTR buffer = EmptyDyn;
  436.     tmplt = strdup(tmplt);
  437.     assert(tmplt != NULL);
  438.     assert (++REK < 8);
  439.     do {
  440.     _NumQueries = 0;
  441.     if (!flexprintf (&buffer, (void *)DynCat, tmplt, n, (void *)NODE_sub)) {
  442. puts (DynValue(&buffer));
  443. ShowLog();
  444.         assert(("FLEXPRINTF - INTERNAL ERROR", 0));
  445.     } /* if */
  446.     free (tmplt);
  447.     tmplt = strdup(DynValue(&buffer));
  448.     assert(tmplt != NULL);
  449.     DynClear(&buffer);
  450.     } while (_NumQueries && --loops);
  451.     _NumQueries = nq_inter;
  452.     DynCat(dest, tmplt);
  453.     free(tmplt);
  454.  
  455.     --REK;
  456.     return (BOOL)1;
  457. } /* NODE_hunt */
  458.  
  459. /* Wir brauchen etwas wie $(@LOCK@shortcut) */
  460.  
  461. struct List locks;
  462.  
  463. struct PNode *get_lock(char *name) {
  464.     struct PNode *n;
  465.     n = FindName ((struct List *)&locks, name);
  466.  
  467. //if (n) printf ("shortcut to %s found\n", name);
  468.  
  469.     return n;
  470. } /* if */
  471.  
  472. char * NODE_Special (struct PNode *n, char *name)
  473. {
  474.     static DSTR retbuffer = EmptyDyn;
  475.     char *pp;
  476.     DSTR buffer = EmptyDyn;
  477.  
  478.     // if (DynLength(&retbuffer))
  479.     //     DynClear(&retbuffer);
  480.     // buffer = EmptyDyn;
  481.  
  482.     if (strnicmp(name, S_ITERATE_, L_ITERATE_) == 0) {
  483.     struct PNode *m;
  484.     int i = 0, ii = Index;
  485.     name += L_ITERATE_;
  486. /* puts("ITERATE..."); */
  487.  
  488.     for (m = GetHead(&n->Subs); m; m = GetSucc(m)) {
  489.         Index = i++;
  490.         if (!NODE_hunt (&buffer, name, m)) {
  491. puts (DynValue(&buffer));
  492. ShowLog();
  493.         assert (("FLEXPRINTF - ERROR", 0));
  494.         } /* if */
  495.     } /* for */
  496.     Index = ii;
  497.  
  498.     goto clean_end;
  499.     } /* if */
  500.     if (strnicmp(name, S_IF_, L_IF_) == 0) {
  501.     name += L_IF_;
  502. /* puts("IF..."); */
  503.     for (pp = name; *pp && (*pp != _END_); ++pp);
  504.     if (*pp) {
  505.         int inv_mode = 0, cond;
  506.         *pp = 0;
  507.         if (*name == '!') {
  508.         ++name;
  509.         inv_mode = 1;
  510.         }
  511. /* printf(name); */
  512.         /* ---- IF-value_not_null */
  513.         name = NODE_sub(n, name);
  514.         *pp = _END_;
  515.  
  516.         cond = name != NULL;
  517.         cond = cond && (atol(name) != 0);
  518.  
  519. /* printf (" cond %d\n", cond != inv_mode); */
  520.         if (cond != inv_mode) {
  521.         if (!NODE_hunt (&buffer, pp + 1, n)) {
  522. puts (DynValue(&buffer));
  523. ShowLog();
  524.             assert (("FLEXPRINTF - ERROR", 0));
  525.         } /* if */
  526.         goto clean_end;
  527.         } else {
  528.         return "";
  529.         } /* if */
  530.  
  531.     } /* if */
  532. ShowLog();
  533.     assert(("IF - BAD CONDITION", 0));
  534.     } /* if */
  535.     if (strnicmp(name, S_WITH_, L_WITH_) == 0) {
  536.     struct PNode *m;
  537.     name += L_WITH_;
  538. /* puts("WITH..."); */
  539.     for (pp = name; *pp && (*pp != _END_); ++pp);
  540.     if (*pp) {
  541.         *pp = 0;
  542.  
  543.  
  544.         m = NODE_lock (n, name, _NOLIMIT_);
  545.         /* m = NODE_lock (n, name, _ONELEVEL_); */
  546.         *pp = _END_;
  547.         if (m) {
  548.         if (!NODE_hunt  (&buffer, pp + 1, m)) {
  549. puts (DynValue(&buffer));
  550. ShowLog();
  551.             assert (("FLEXPRINTF - ERROR", 0));
  552.         } /* if */
  553.         goto clean_end;
  554.         } /* if */
  555.  
  556. ShowLog();
  557.         assert (("WITH - NAME NOT FOUND", 0));
  558.  
  559.     } /* if */
  560. ShowLog();
  561.     assert (("WITH - BAD NAME", 0));
  562.     } /* if */
  563.     if (strnicmp(name, S_FOREACH_, L_FOREACH_) == 0) {
  564.     struct PNode *m;
  565.     name += L_FOREACH_;
  566. //puts("FOREACH...");
  567.     for (pp = name; *pp && (*pp != _END_); ++pp);
  568.     if (*pp) {
  569.         int ii = Index, it = TIndex;
  570.         *pp = 0;
  571.         TIndex = Index = 0;
  572. //printf("%s in %s/%08lx...\n", name, n->Node.ln_Name, n);
  573.         for (m = GetHead(&n->Subs); m; m = GetSucc(m)) {
  574.         ++ Index;
  575. //printf(" ? %s ?\n", m->Node.ln_Name);
  576.         if (m->Type && !stricmp(m->Type->Node.ln_Name, name)) {
  577.             ++TIndex;
  578. //puts ("     Yea!");
  579.             if (!NODE_hunt  (&buffer, pp + 1, m)) {
  580. puts (DynValue(&buffer));
  581. ShowLog();
  582.             assert (("FLEXPRINTF - ERROR", 0));
  583.             } /* if */
  584.         } /* if */
  585.         } /* for */
  586.  
  587.         TIndex = it;
  588.         Index  = ii;
  589.         *pp    = _END_;
  590.         goto clean_end;
  591.     } /* if */
  592. ShowLog();
  593.     assert (("FOREACH - BAD NAME", 0));
  594.     } /* if */
  595.     if (strnicmp(name, S_TOUPPER_, L_TOUPPER_) == 0) {
  596.     name += L_TOUPPER_;
  597.     if (!NODE_hunt (&buffer, name, n)) {
  598. puts (DynValue(&buffer));
  599. ShowLog();
  600.         assert (("FLEXPRINTF - ERROR", 0));
  601.     } /* if */
  602.     strupper(DynValue(&buffer));
  603.     goto clean_end;
  604.     } /* if */
  605.     if (strnicmp(name, S_TOLOWER_, L_TOLOWER_) == 0) {
  606.     name += L_TOLOWER_;
  607.     if (!NODE_hunt (&buffer, name, n)) {
  608. puts (DynValue(&buffer));
  609. ShowLog();
  610.         assert (("FLEXPRINTF - ERROR", 0));
  611.     } /* if */
  612.     strlower(DynValue(&buffer));
  613.     goto clean_end;
  614.     } /* if */
  615.     if (!strnicmp (name, "@debug@", 7)) {
  616.     void NODE_TREE (struct PNode *p, APTR pa);
  617. puts ("DEBUG");
  618.     NODE_TREE(n, NULL);
  619.     exit(0);
  620.     } /* if */
  621.     if (!strnicmp (name, "@lock@", 6)) {
  622.     struct PNode *p;
  623.     name += 6;
  624.     //NODE_PUSH(name);
  625.     //NODE_POP();
  626.  
  627.     for (pp = name; *pp && (*pp != _END_); ++pp);
  628.     if (*pp) {
  629.         *pp = 0;
  630. //printf ("locking %s as %s\n", n->Node.ln_Name, name);
  631.         if (NEW(p)) {
  632.         p->Node.ln_Name = name;
  633.         DynCpy(&p->Text, n->Node.ln_Name);
  634.         AddHead((struct List *)&locks, &p->Node);
  635.  
  636. //{struct PNode *n;
  637. //for (n = GetHead (&locks);n;n = GetSucc(n)) {
  638. //    printf ("locked %s\n", n->Node.ln_Name);
  639. //    get_lock (n->Node.ln_Name);
  640. //} /* for */
  641. //}
  642.  
  643.         if (!NODE_hunt  (&buffer, pp + 1, n)) {
  644. puts (DynValue(&buffer));
  645. ShowLog();
  646.             assert (("FLEXPRINTF - ERROR", 0));
  647.         } /* if */
  648.  
  649.         Remove (&p->Node);
  650.         DynClear(&p->Text);
  651.         free(p);
  652.         } else {
  653. ShowLog();
  654.         assert("Alloc" == NULL);
  655.         } /* if */
  656.         *pp = _END_;
  657.         goto clean_end;
  658.     } /* if */
  659.     } /* if */
  660.  
  661.  
  662.     return NULL;
  663.  
  664. clean_end:
  665.     DynDCpy(&retbuffer, &buffer);
  666.     DynClear(&buffer);
  667.     return DynValue (&retbuffer);
  668. } /* NODE_Special */
  669.  
  670.  
  671. char * __NODE_sub (struct PNode *n, char *name)
  672. {
  673.     char *res;
  674.  
  675.  
  676.     if (!n) {
  677.     void NODE_TREE (struct PNode *p, APTR pa);
  678.     n = GetHead(&NStack);
  679.     assert (n != NULL);
  680. //NODE_TREE(n, NULL);
  681.     }
  682.  
  683. //printf ("Q:4'%s'in'%s'\n", name, n->Node.ln_Name);
  684.  
  685.  
  686.     res = NULL;
  687.     res = NULL;
  688.     {
  689.     if (name[0] == '?')
  690.         return (NODE_lock (n, name + 1, _NOLIMIT_))? "1": "0";
  691.         /* return (NODE_lock (n, name + 1, _ONELEVEL_))? "1": "0"; */
  692.     if ((name[0] == '!') && (name[1] == '?'))
  693.         return (NODE_lock (n, name + 2, _NOLIMIT_))? "0": "1";
  694.         /* return (NODE_lock (n, name + 2, _ONELEVEL_))? "0": "1"; */
  695.  
  696.     if (stricmp(_NAME_, name) == 0) {
  697.         return n->Node.ln_Name;
  698.     } /* if */
  699.     if (stricmp("__type", name) == 0) {
  700.         return n->Type ? n->Type->Node.ln_Name: "";
  701.     } /* if */
  702.     if (stricmp(_SETTABLE_, name) == 0) {
  703.         return (n->Node.ln_Pri & CA_CONST) ? "0": "1";
  704.     } /* if */
  705.     if (stricmp(_GETTABLE_, name) == 0) {
  706.         return (n->Node.ln_Pri & CA_HIDDEN) ? "0": "1";
  707.     } /* if */
  708.     if (stricmp(_VALUE_, name) == 0) {
  709.         return DynValue(&n->Text);
  710.     } /* if */
  711.     if (stricmp(_INDEX_, name) == 0) {
  712.     static char rb2[16];
  713.         sprintf (rb2, "%d", Index);
  714.         return rb2;
  715.     } /* if */
  716.     if (stricmp(_TINDEX_, name) == 0) {
  717.     static char rb3[16];
  718.         sprintf (rb3, "%d", TIndex);
  719.         return rb3;
  720.     } /* if */
  721.  
  722.     if (*name == _END_) {
  723.         return NODE_Special(n, name);
  724.     } /* if */
  725.     }
  726.  
  727.     {
  728.     struct PNode *x;
  729.     if ((x = get_lock(name))) {
  730. //printf ("wanting %s from %s\n", DynValue(&x->Text), x->Node.ln_Name);
  731. //fflush(stdout);
  732.         return NODE_sub(x, _VALUE_);
  733.     }
  734.     }
  735.  
  736.     res = _NODE_sub(n, name);
  737.     ++_NumQueries;
  738.  
  739.     if (!res) {
  740.     printf ("FAIL: %s/%s!\n", n->Node.ln_Name, name);
  741.     }
  742.  
  743.     /* return res; */
  744.  
  745.     { /* /* ---- HIER muss das TRACE-DOWN HIN!!!!! */
  746.     DSTR buffer = EmptyDyn;
  747. static DSTR retbuffer = EmptyDyn;
  748.     if (!flexprintf (&buffer, (void *)DynCat, res, n, (void *)NODE_sub)) {
  749. puts (DynValue(&buffer));
  750. ShowLog();
  751.         assert(("FLEXPRINTF - INTERNAL ERROR", 0));
  752.     } /* if */
  753.  
  754.     DynDCpy(&retbuffer, &buffer);
  755.     DynClear(&buffer);
  756.     return DynValue(&retbuffer);
  757.     }
  758.  
  759.  
  760. } /* NODE_sub */
  761.  
  762. void DropLog (void);
  763.  
  764. char * NODE_sub (struct PNode *n, char *name) {
  765.     static int level = 0;
  766.     Log (name, level, n);
  767.     ++level;
  768.     name = __NODE_sub (n, name);
  769.     --level;
  770.     DropLog();
  771.     return name;
  772. }
  773.  
  774.  
  775. void NODE_init (void)
  776. {
  777.     //atexit (ShowLog);
  778.     NewList(&NStack);
  779.     NewList(&_private_init);
  780.     NewList((struct List *)&locks);
  781.     NODE_PUSH("ROOT", 1);
  782.     NODE_root = GetHead (&NStack);
  783. } /* NODE_init */
  784.  
  785.  
  786.  
  787.  
  788. void ResetNumQueries (void)
  789. {
  790.     _NumQueries = 0;
  791. } /* ResetNumQueries */
  792.  
  793. int NumQueries (void)
  794. {
  795.     return _NumQueries;
  796. } /* NumQueries */
  797.  
  798.  
  799. void NODE_TREE (struct PNode *p, APTR pa) {
  800.     static int counter = 0;
  801.     int i;
  802.     struct PNode *c;
  803.  
  804.     if (!counter && !p) {
  805.     for (p = GetTail (&NStack); p; p = GetPred(p)) {
  806.         ++counter;
  807.         NODE_TREE(p, GetSucc(p));
  808.     }
  809.     counter = 0;
  810.     return;
  811. //      p = GetHead(&NStack);
  812.     }
  813. //      p = NODE_root;
  814.  
  815.     ++ counter;
  816.  
  817.     for (i = 0; i < counter; ++i) printf ("  ");
  818.     printf ("[%d]a=%08lx t=%08lx n='%s' p=%08lx?=%08lx\n", counter, p, p->Type, p->Node.ln_Name, p->Parent,pa);
  819.     if (GetHead(&p->Types)) {
  820.     for (i = 0; i < counter; ++i) printf ("  ");
  821.     printf (" [%d]types:\n", counter);
  822.     for (c = GetHead(&p->Types); c; c = GetSucc (c))
  823.         NODE_TREE (c,p);
  824.     }
  825.     if (GetHead(&p->Subs)) {
  826.     for (i = 0; i < counter; ++i) printf ("  ");
  827.     printf (" [%d]subs:\n", counter);
  828.     for (c = GetHead(&p->Subs); c; c = GetSucc (c))
  829.         NODE_TREE (c,p);
  830.     }
  831.     -- counter;
  832. } /* NODE_TREE */
  833.  
  834.  
  835. struct List Logs = {0L,0L,0L};
  836. void Log (char *text, int level, struct PNode *nn) {
  837.     struct Node *n;
  838.  
  839.     if (!Logs.lh_Head)
  840.     NewList (&Logs);
  841.  
  842.     if (NEW(n)) {
  843.     AddTail(&Logs, n);
  844.     n->ln_Pri  = level;
  845.     n->ln_Name = strdup (text);
  846.     }
  847. }
  848.  
  849. void DropLog (void)
  850. {
  851.     struct Node *n;
  852.     if (!Logs.lh_Head)
  853.     NewList (&Logs);
  854.  
  855.     n = RemTail (&Logs);
  856.     if (n) {
  857.     free (n->ln_Name);
  858.     free (n);
  859.     }
  860. } /* DropLog */
  861.  
  862.  
  863. void ShowLog (void) {
  864.     struct Node *n;
  865.  
  866.     if (!Logs.lh_Head)
  867.     NewList (&Logs);
  868.  
  869.     for (n = GetHead (&Logs); n; n = GetSucc(n))
  870.     printf ("%d: %-20.20s\n", (int)n->ln_Pri, n->ln_Name);
  871. }
  872.